/********************************************************************
 *
 *      Filename: Quaternion.h
 *   Description: Class form quaternions
 *        Author: [kb]ypp
 *    Created at: February 22, 2005
 * Last modified: November 5, 2005
 *
 ********************************************************************/

#ifndef QUATERNION_H
#define QUATERNION_H

class vec3;
class mat3;

//! @brief Class to represent a unit quaternion
//!
//! That is, any quaternion is assumed to to have a unit length
class quat {
public:
	// Quaternion representation:
	//      q = [ w v ] = [ w ( x y z ) ]
	float w, x, y, z;
	
	//! @brief Default constructor
	quat();
	//! @brief Copy-constructor
	quat( const quat &q );
	//! @brief Constructor to initalize the quaternion with given components
	quat( float qw, float qx, float qy, float qz );
	
	//! @brief Assignment operator
	const quat& operator=( const quat &q );
	//! @brief Quaternion multiplication
	friend const quat operator*( const quat &q1, const quat &q2 );
	
	//! @brief Equality (with tolerance) check
	friend bool operator==( const quat &q1, const quat &q2 );
	//! @brief Non-equality (with tolerance) check
	friend bool operator!=( const quat &q1, const quat &q2 );
	
	//! @brief Quaternion normalization
	void normalize();
	//! @brief Get the rotation matrix corresponding to the quaternion
	const mat3 toMatrix() const;
	//! @brief Calculate the conjugate quaternion
	friend const quat conj( const quat &q );
	//! @brief Spherical linear interpolation of quaternions
	friend const quat slerp( const quat &q0, const quat &q1, float t );
	
	//! @brief Get the quaternion to perform rotation about the x-axis
	static const quat rotateX( float theta );
	//! @brief Get the quaternion to perform rotation about the y-axis
	static const quat rotateY( float theta );
	//! @brief Get the quaternion to perform rotation about the z-axis
	static const quat rotateZ( float theta );
	//! @brief Get the quaternion to perform rotation about an arbitrary axis
	static const quat rotateAxis( const vec3 &axis, float theta );
};

#endif // QUATERNION_H
